package com.nsl.my_youlai.bbu2.service.impl;

import com.nsl.my_youlai.bbu2.enums.BbuModelEnum;
import com.nsl.my_youlai.bbu2.enums.BoardTypeEnum;
import com.nsl.my_youlai.bbu2.enums.VendorEnum2;
import com.nsl.my_youlai.bbu2.model.bo.bbu.*;
import com.nsl.my_youlai.bbu2.model.bo.bbu.instances.*;
import com.nsl.my_youlai.bbu2.model.bo.bbu.rules.BbuSlotRule;
import com.nsl.my_youlai.bbu2.model.vo.BbuStatusExcelStringVo;
import com.nsl.my_youlai.mystar.enums.NslEnumBaseI;
import com.nsl.my_youlai.mystar.enums.NslEnumTransformException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class BbuServiceImpl {

    public Map<Integer, Bbu2> buildBbuMap(List<BbuStatusExcelStringVo> voList) throws NslEnumTransformException {
        Map<Integer, Bbu2> bbuFrameMap = new HashMap<>();
        for (BbuStatusExcelStringVo vo : voList) {
            int excelRowIndex = vo.getRowIndex();
            Integer nodeId = Integer.parseInt(vo.getNodeBId());
            VendorEnum2 vendor = NslEnumBaseI.getEnumByLabel(vo.getVendor(), VendorEnum2.class);
            BbuModelEnum bbuModelEnum = NslEnumBaseI.getEnumByLabel(vo.getBbuModel(), BbuModelEnum.class);

            BoardTypeEnum boardTypeEnum = NslEnumBaseI.getEnumByLabel(vo.getBoardType(), BoardTypeEnum.class);

            Bbu2 bbu = null;
            if (bbuFrameMap.keySet().contains(nodeId)) {
                bbu = bbuFrameMap.get(nodeId);
            } else {
                bbu = vo2Bbu(excelRowIndex, vendor, bbuModelEnum, nodeId);
                bbu.setApparatusRoomId(vo.getApparatusRoomId());
                bbuFrameMap.put(nodeId, bbu);
            }




            if (boardTypeEnum == BoardTypeEnum.FRAME_AND_FUN) {
                BbuFrame bbuFrame = vo2BbuFrame(excelRowIndex, vendor, bbuModelEnum, nodeId);
                BbuFun bbuFun = vo2BbuFun(excelRowIndex, vendor, bbuModelEnum, nodeId);
                bbu.getBbuFunList().add(bbuFun);
                bbu.getBbuFrameList().add(bbuFrame);

            } else if (boardTypeEnum == BoardTypeEnum.BASE_BAND_BOARD || boardTypeEnum == BoardTypeEnum.CONTROL_BOARD || boardTypeEnum == BoardTypeEnum.POWER_BOARD || boardTypeEnum == BoardTypeEnum.SWITCH_BOARD) {
                BbuBoard2 bbuBoard = vo2BbuBoard(excelRowIndex, vendor, bbuModelEnum, nodeId, boardTypeEnum);

                BbuSlot2 bbuSlot = null;
                Map<Integer, BbuSlot2> slotMap = bbu.getSlotMap();
                Integer slotIndex = Integer.parseInt(vo.getSlotIndex());

                if (slotMap.keySet().contains(slotIndex)) {
                    bbuSlot = slotMap.get(slotIndex);
                } else {
                    bbuSlot = vo2BbuSlot(excelRowIndex, vendor, bbuModelEnum, nodeId, boardTypeEnum, slotIndex);
                    slotMap.put(slotIndex, bbuSlot);
                    bbu.getSoltIndexList().add(slotIndex);
                }
                bbuBoard.setSlotIndex(bbuSlot.getSlotIndex());
                bbuSlot.getBbuBoardList().add(bbuBoard);
            }
        }
        return bbuFrameMap;
    }

    private BbuSlot2 vo2BbuSlot(int excelRowIndex, VendorEnum2 vendor, BbuModelEnum bbuModelEnum, Integer nodeId, BoardTypeEnum boardTypeEnum, Integer slotIndex) {
        BbuSlot2 bbuSlot = new BbuSlot2(excelRowIndex, vendor, bbuModelEnum, nodeId, boardTypeEnum, slotIndex);
        return bbuSlot;
    }

    private BbuBoard2 vo2BbuBoard(int excelRowIndex, VendorEnum2 vendor, BbuModelEnum bbuModelEnum, Integer nodeId, BoardTypeEnum boardTypeEnum) {
        BbuBoard2 bbuBoard = new BbuBoard2(excelRowIndex, vendor, bbuModelEnum, nodeId, boardTypeEnum);
        return bbuBoard;
    }

    private BbuFrame vo2BbuFrame(int excelRowIndex, VendorEnum2 vendor, BbuModelEnum bbuModelEnum, Integer nodeId) {
        BbuFrame bbuFrame = new BbuFrame(excelRowIndex, vendor, bbuModelEnum, nodeId);
        return bbuFrame;
    }

    private BbuFun vo2BbuFun(int excelRowIndex, VendorEnum2 vendor, BbuModelEnum bbuModelEnum, Integer nodeId) {
        BbuFun bbuFun = new BbuFun(excelRowIndex, vendor, bbuModelEnum, nodeId);
        return bbuFun;
    }


    public Bbu2 vo2Bbu(int excelRowIndex, VendorEnum2 vendor, BbuModelEnum bbuModelEnum, Integer nodeId) throws NslEnumTransformException {
        Bbu2 bbu = null;
        switch (bbuModelEnum) {
            case BBU_5900 :{
                bbu = new BbuHw5g5900(excelRowIndex, vendor, bbuModelEnum, nodeId);
                break;
            }
            case BBU_3900: {
                bbu = new BbuHw4g3900(excelRowIndex, vendor, bbuModelEnum, nodeId);
                break;
            }
            case BBU_3910 :{
                bbu = new BbuHw4g3910(excelRowIndex, vendor, bbuModelEnum, nodeId);
                break;
            }
            case BBU_B8200: {
                bbu = new BbuZx4gB8200(excelRowIndex, vendor, bbuModelEnum, nodeId);
                break;
            }
            case BBU_V9200 :{
                bbu = new BbuZx5gV9200(excelRowIndex, vendor, bbuModelEnum, nodeId);
                break;
            }
            case BBU_EMB6216:{
                bbu = new BbuDt5gEmb6212(excelRowIndex, vendor, bbuModelEnum, nodeId);
                break;
            }
        }


        return bbu;
    }


    public  List<BbuRecordCheckError> checkSlotRules(Bbu2 bbu){
        List<BbuRecordCheckError> bbuRecordCheckErrorArrayList=new ArrayList<>();
        Map<Integer,BbuSlotRule> slotRuleMap=bbu.getSlotRules().getBbuSlotRuleMap();
        for (Integer integer : bbu.getSoltIndexList()) {
            BbuSlot2 bbuSlot=bbu.getSlotMap().get(integer);
            BbuSlotRule bbuSlotRule=slotRuleMap.get(integer);
            if(bbuSlotRule==null){
                BbuRecordCheckError bbuRecordCheckError=new BbuRecordCheckError();
                bbuRecordCheckError.setExcelRowIndex(bbuSlot.getExcelRowIndex());
                bbuRecordCheckError.setErrorType("插槽规则未定义");
                bbuRecordCheckError.setErrorMessage("插槽 不存在或不在本次校验范围内");
                bbuRecordCheckErrorArrayList.add(bbuRecordCheckError);
                continue;
            }

            List<BbuRecordCheckError> subList=bbuSlotRule.check(bbuSlot);

            bbuRecordCheckErrorArrayList.addAll(subList);
        }
        return bbuRecordCheckErrorArrayList;
    }

    public List<BbuRecordCheckError> checkSlotRules(List<Bbu2> bbuList){
        List<BbuRecordCheckError> bbuRecordCheckErrorArrayList=new ArrayList<>();
        for (Bbu2 bbu2 : bbuList) {
            List<BbuRecordCheckError> subList=checkSlotRules(bbu2);
            bbuRecordCheckErrorArrayList.addAll(subList);
        }
        return bbuRecordCheckErrorArrayList;
    }

    public List<BbuRecordCheckError> checkSlotRules(Map<Integer, Bbu2> bbuMap){
        List<BbuRecordCheckError> bbuRecordCheckErrorArrayList=new ArrayList<>();
        for (Map.Entry<Integer, Bbu2> entry : bbuMap.entrySet()) {
           Bbu2 bbu2=entry.getValue();
           List<BbuRecordCheckError> subList=checkSlotRules(bbu2);
           bbuRecordCheckErrorArrayList.addAll(subList);

        }
        return bbuRecordCheckErrorArrayList;
    }
}
